package pers.cz.controller;

import cn.hutool.core.date.DateUtil;
import org.springframework.util.StreamUtils;
import pers.cz.exception.ErrorCode;
import pers.cz.exception.BusinessException;
import pers.cz.minio.MinioUtils;
import pers.cz.model.RecordResult;
import pers.cz.model.TestCase;
import pers.cz.model.TestCaseParams;
import pers.cz.pub.BeanHelper;
import pers.cz.pub.CpublicFunc;
import pers.cz.pub.RespBean;
import pers.cz.pub.SequenceEnum;
import pers.cz.regularexpression.ExpressionUtils;
import pers.cz.http.HttpUtils;
import pers.cz.service.TestCaseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import pers.cz.spring.SpringContextUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: PostGirl-panent
 * @description: QueryTestCaseController
 * @author: Cheng Zhi
 * @create: 2021-03-12 16:45
 **/
@RestController
@Api(tags = "案例管理接口")
@RequestMapping("/api/queryTestCase")
public class TestCaseController {

    Logger log = LoggerFactory.getLogger(TestCaseController.class);
    @Autowired
    TestCaseService queryTestCaseService;

    @Autowired
    MinioUtils minioUtils;

    @ApiOperation(value = "根据案例名称获取测试案例")
    @GetMapping("/getAllTestCaseByTestName")
    public List<TestCase> getAllTestCaseByTestName(Map map) {
        String testName = (String) map.get("testName");
        if (testName == null && "".equals(testName)) {
            return null;
        }

        return queryTestCaseService.getAllTestCaseByTestName(testName);

    }
    @ApiOperation(value = "获取案例总数据量")
    @GetMapping("/queryCountTestCase")
    public int getCountTestCase(HttpServletRequest request) {

        int userId = Integer.valueOf(request.getAttribute("userId").toString());
        int count = queryTestCaseService.getCountTestCase(userId);
        return count;
    }

    @ApiOperation(value = "查询全部案例")
    @GetMapping("/queryAllTestCase")
    public List<TestCase> getAllTestCase() {

        List<TestCase> testCaseList = queryTestCaseService.getAllTestcase();

        return testCaseList;
    }

    @ApiOperation(value = "分页查询全部案例")
    @PostMapping("/queryAllTestCaseByPage")
    public List<TestCase> getAllTestCaseByPage(@RequestBody Map map, HttpServletRequest request) throws IOException {

        int userId = Integer.valueOf(request.getAttribute("userId").toString());
        int pageStart = (int) map.get("pageStart");
        int pageLimit = (int) map.get("pageLimit");
        List<TestCase> testCaseList = queryTestCaseService.getAllTestcaseByPage(pageStart, pageLimit, userId);

        return testCaseList;
    }

    @ApiOperation(value = "根据接口编号查询案例")
    @PostMapping("/queryTestCaseByBusiCode")
    public List<TestCase> getTestCaseByBusiCode(@RequestParam(value = "busiCode", required = false) String busiCode) {

        List<TestCase> testCaseList = queryTestCaseService.getAllTestcase(busiCode);

        return testCaseList;
    }

    @ApiOperation(value = "根据多个id查询案例")
    @PostMapping("/queryAllTestCaseIds")
    public List<TestCase> queryAllTestCaseIds(@RequestParam(value = "busiCode") List<Integer> ids) {

        String result;
        List<TestCase> testCaseList = queryTestCaseService.queryAllTestCaseIds(ids);

        for (TestCase testCase : testCaseList) {
            // result = RequestReturnResponse.getResultByPost(testCase.getRequest(),testCase.getUrl());
            // 将结果写入到表中


        }
        return testCaseList;
    }

    @ApiOperation(value = "根据id查询案例")
    @PostMapping("/queryTestCaseById")
    public TestCase queryTestCaseById(@RequestParam(value = "id") Integer id) {

        TestCase testCase = queryTestCaseService.queryTestCaseById(id);

        return testCase;
    }

    @ApiOperation(value = "录制案例")
    @PostMapping("/recordCase")
    public RespBean recordCase(@RequestBody Map map) {

        String request = (String) map.get("request");
        String url = (String) map.get("url");

        Map<String, String> header = new HashMap<String, String>();
        BeanHelper daoHelper = SpringContextUtil.getBean(BeanHelper.class);
        CpublicFunc cpublicFunc = new CpublicFunc(daoHelper);
        String caseId = String.valueOf(cpublicFunc.getSoNbr(SequenceEnum.TESTCASE_ID_SEQUENCE));
        header.put("caseId", caseId);
        header.put("type", "RECORD");

        String result = HttpUtils.post(request, url, header);
        RecordResult recordResult = new RecordResult();
        recordResult.setCaseId(caseId);
        recordResult.setResponse(result);

        return RespBean.ok("录制成功", recordResult);
    }

    @ApiOperation(value = "重新录制案例")
    @PostMapping("/reRecordCase")
    public RespBean reRecordCase(@RequestBody Map map) {

        String request = (String) map.get("request");
        String url = (String) map.get("url");
        String caseId = (String) map.get("caseId");

        Map<String, String> header = new HashMap<String, String>();
        header.put("caseId", caseId);
        header.put("type", "RECORD");

        String result = HttpUtils.post(request, url, header);

        return RespBean.ok("重新录制成功", result);
    }

    @ApiOperation(value = "添加测试案例")
    @PostMapping("/addTestCase")
    //public RespBean addTestCase(@RequestParam(value = "request") String request, @RequestParam(value = "expectedResponse") String expectedResponse, @RequestParam(value = "busiCode") String busiCode, @RequestParam(value = "ignoreFields") String ignoreFields) {
    public RespBean addTestCase(@RequestBody Map map, HttpServletRequest requestServlet) {
        int userId = Integer.valueOf(requestServlet.getAttribute("userId").toString());
       if (map.get("request") == null || map.get("expectedResponse") == null ||  map.get("busiCode") == null || map.get("caseName") == null) {
            throw new BusinessException(ErrorCode.REQUEST_IS_NULL_ERROR);
        }
        Integer caseId = Integer.valueOf((String)map.get("caseId"));
        String caseName = (String) map.get("caseName");
        String request = (String) map.get("request");
        String expectedResponse = (String) map.get("expectedResponse");
        String busiCode = (String) map.get("busiCode");
        String ignoreFields = (String) map.get("ignoreFields");
        String caseNameZh = (String) map.get("caseNameZh");

        int count = queryTestCaseService.addTestCase(caseId, caseName,request, expectedResponse, busiCode, ignoreFields, caseNameZh,userId);
        return RespBean.ok("添加成功", count);
    }

    @ApiOperation(value = "修改测试案例")
    @PostMapping("/updateTestCase")
    public RespBean updateTestCase(@RequestParam(value = "id") Integer id, @RequestParam(value = "request") String request, @RequestParam(value = "expectedResponse") String expectedResponse, @RequestParam(value = "busiCode") String busiCode, @RequestParam(value = "ignoreFields", required = false) String ignoreFields) {

        TestCase testCase = new TestCase();
        testCase.setId(id);
        testCase.setRequest(request);
        testCase.setExpectedResponse(expectedResponse);
        testCase.setBusiCode(busiCode);
        testCase.setIgnoreFields(ignoreFields);
        testCase.setCreateDate(DateUtil.date());
        if (ignoreFields == null ) {
            ignoreFields = "";
        }
        testCase.setIgnoreFields(ignoreFields);

        int count = queryTestCaseService.updateTestCase(testCase);
        return RespBean.ok("修改成功", count);
    }

    @ApiOperation(value = "删除测试案例")
    @PostMapping("/deleteTestCase")
    public RespBean deleteTestCase(@RequestBody Map map) {
        int id = (int) map.get("id");
        int count = queryTestCaseService.deleteTestCase(id);
        return RespBean.ok("删除成功", count);
    }

    @ApiOperation(value = "查询所有的测试案例编号和案例名称")
    @GetMapping("/queryAllIdAndCaseName")
    public Map<Integer,List<String>> queryAllIdAndCaseName(HttpServletRequest request) {

        Map<Integer,List<String>> map = new HashMap<>(); // 这里最好指定一下Map的大小？
        map = queryTestCaseService.selectAllIdAndCaseName();
        return map;
    }

    @ApiOperation(value = "文件预览")
    @GetMapping("/preview")
    //public String preview(@RequestBody Map map, HttpServletResponse response) throws IOException {
    public String preview() throws IOException {
        // String path = (String) map.get("path");
        String path = "D:\\Java\\Project\\PostGirl-panent\\report\\69367.html";
        File file = new File(path);
        byte[] bytes = StreamUtils.copyToByteArray(new FileInputStream(file));
        String content = new String(bytes, StandardCharsets.UTF_8);
        return content;
    }

    /**
     * 文件导出
     * @return
     */
    @ApiOperation(value = "文件导出")
    @PostMapping("/download")
    public void download(@RequestBody Map map, HttpServletResponse response) {
        try {
            String path = (String) map.get("path");
            // path是指想要下载的文件的路径
            File file = new File(path);
            log.info(file.getPath());
            // 获取文件名
            String filename = file.getName();
            // 获取文件后缀名
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
            log.info("文件后缀名：" + ext);

            // 将文件写入输入流
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStream fis = new BufferedInputStream(fileInputStream);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
            // 告知浏览器文件的大小
            response.addHeader("Content-Length", "" + file.length());
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            outputStream.write(buffer);
            outputStream.flush();
        } catch (IOException ex) {

            if (ex instanceof FileNotFoundException) {
               throw new BusinessException(ErrorCode.FILE_NOT_FOUND_ERROR);
            }
            ex.printStackTrace();
        }
    }

    @GetMapping(path = "/testException")
    public RespBean testException() {
        System.out.println("跳过异常");
        int i = 1;
        if (i == 1) {
            throw new BusinessException(ErrorCode.FILE_ANALYSE_ERROR);
        }
        return null;
    }

    @PostMapping(path = "/getTestZip")
    public void getTestZip(HttpServletResponse response) throws IOException {

        // 清空response
        response.reset();
        // 设置response的Header
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("tttt.zip", "UTF-8"));
        response.setHeader("code","200");

        //
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        InputStream inputStream = new FileInputStream("D:\\test\\H5菜单后台接口开发进度.xlsx");
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        byte[] bytes = new byte[100];
        int len;
        while ((len = inputStream.read(bytes)) > 0) {
            outputStream.write(bytes,0,len);
        }
        inputStream.close();
        outputStream.flush();
        outputStream.close();
    }

    @ApiOperation(value = "模糊查询测试案例")
    @PostMapping("/queryTestCaseByFuzzy")
    public List<TestCase> queryTestCaseByFuzzy(@RequestBody Map map) {

        String testCaseName = (String) map.get("testCaseName");
        return queryTestCaseService.getAllTestCaseByFuzzy(testCaseName);
    }

    @ApiOperation(value = "分页案例参数")
    @PostMapping("/queryTestCaseParams")
    public List<TestCaseParams> queryTestCaseParams(@RequestBody Map map) {

        int pageStart = (int) map.get("pageStart");
        int pageLimit = (int) map.get("pageLimit");

        return queryTestCaseService.queryAllTestCaseParams(pageStart, pageLimit);
    }

    @ApiOperation(value = "添加案例参数")
    @PostMapping("/addTestCaseParams")
    public Integer addTestCaseParams(@RequestBody Map map) {

        String paramName = (String) map.get("paramName");
        String paramValue = (String) map.get("paramValue");
        Integer generate = (Integer) map.get("generate");
        String rule = (String) map.get("rule");
        String ext1 = (String) map.get("ext1");

        TestCaseParams testCaseParams = new TestCaseParams();
        testCaseParams.setParamName(paramName);
        testCaseParams.setGenerate(String.valueOf(generate));
        testCaseParams.setGenerateRule(rule);
        testCaseParams.setParamValue(paramValue);
        testCaseParams.setExt1(ext1);

        return queryTestCaseService.addTestCaseParam(testCaseParams);
    }

    @ApiOperation(value = "修改案例参数")
    @PostMapping("/updateTestCaseParams")
    public Integer updateTestCaseParams(@RequestBody Map map) {

        String paramName = (String) map.get("paramName");
        String paramValue = (String) map.get("paramValue");
        Integer generate = (Integer) map.get("generate");
        Integer id = (Integer) map.get("id");
        String rule = (String) map.get("rule");
        String ext1 = (String) map.get("ext1");

        TestCaseParams testCaseParams = new TestCaseParams();
        testCaseParams.setId(id);
        testCaseParams.setParamName(paramName);
        testCaseParams.setGenerate(String.valueOf(generate));
        testCaseParams.setGenerateRule(rule);
        testCaseParams.setParamValue(paramValue);
        testCaseParams.setExt1(ext1);

        return queryTestCaseService.updateTestCaseParam(testCaseParams);
    }

    @ApiOperation(value = "删除案例参数")
    @PostMapping("/deleteTestCaseParams")
    public Integer deleteTestCaseParams(@RequestBody Map map) {

        Integer id = (Integer) map.get("id");
        return queryTestCaseService.deleteTestCaseParam(id);
    }

    @ApiOperation(value = "获取案例总数，用于分页")
    @GetMapping("/getCount")
    public Integer getCount() {

        return queryTestCaseService.getCountTestCaseParam();
    }

    @ApiOperation(value = "根据id查询测试参数")
    @PostMapping("/queryTestCaseParamById")
    public Integer queryTestCaseParamById(@RequestBody Map map) {

        Integer id = (Integer) map.get("id");
        return queryTestCaseService.deleteTestCaseParam(id);
    }

    @ApiOperation(value = "调试正则表达式")
    @PostMapping("/debugParamExpression")
    public RespBean debugParamExpression(@RequestBody Map map) {

        String expression = (String) map.get("expression");
        try {
            String result = ExpressionUtils.random(expression);
            return RespBean.ok("调试通过" + result);
        } catch (Exception e) {
            return RespBean.error("调试失败:"+ e.getMessage());
        }
    }
}
